package com.xhwl.logistics.converter.mapstruct;

import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.pojo.cent.device.Device;
import com.xhwl.logistics.bo.cent.DeviceBO;
import com.xhwl.logistics.dto.http.DeviceInfoCoSonDTO;
import com.xhwl.logistics.dto.http.ParkingLotDeviceInfoKeTopDTO;
import com.xhwl.logistics.dto.query.CarDeviceJieShunDTO;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.mapstruct.InheritInverseConfiguration;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.NullValueMappingStrategy;

import java.util.List;
import java.util.stream.Collectors;

@Mapper(componentModel = "spring", nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT)
public interface CentDeviceConverter {

    @Getter
    @AllArgsConstructor
    enum JieShunInputOutputType {
        WEI_QI_YONG(0, "未启用"),
        DA_CHE_CHANG_RU_KOU(1, "大车厂入口"),
        DA_CHE_CHANG_CHU_KOU(2, "大车厂出口"),
        XIAO_CHE_CHANG_RU_KOU(3, "小车厂入口"),
        XIAO_CHE_CHANG_CHU_KOU(4, "小车厂出口"),
        ZHONG_YANG_SHOU_FEI_JI(5, "中央收费机"),
        ZHONG_YANG_SHOU_FEI_CHU_KOU(6, "中央收费出口");
        private Integer id;
        private String description;

        public static String toDescription(Integer id) {
            for (JieShunInputOutputType jieShunInputOutputType : JieShunInputOutputType.values()) {
                if (jieShunInputOutputType.id.equals(id)) {
                    return jieShunInputOutputType.description;
                }
            }
            throw new BusinessException("捷顺设备出入类型，枚举转换失败，转换失败的id：" + id);
        }
    }

    @Mapping(target = "onlineStatus", ignore = true)
    default DeviceDTO device2DeviceDTO(Device device) {
        DeviceDTO deviceDTO = new DeviceDTO();

        if (device != null && device.getOnlineStatus() != null) {
            deviceDTO.setOnlineStatus(device.getOnlineStatus().getId());
        }

        return deviceDTO;
    }

    List<DeviceBO> deviceDTOList2DeviceBOList(List<DeviceDTO> deviceDTOList);

    @Mapping(source = "iotDeviceId", target = "number")
    @Mapping(source = "detailPosition", target = "position")
    DeviceBO deviceDTO2DeviceBO(DeviceDTO deviceDTO);

    List<DeviceDTO> deviceBOList2DeviceDTOList(List<DeviceBO> deviceBOList);

    @InheritInverseConfiguration
    @Mapping(target = "deviceTypeId", constant = "3")
//    @Mapping(target = "onlineStatus", constant = "1")
    DeviceDTO deviceBO2DeviceDTO(DeviceBO deviceBO);

    List<Device> deviceBOList2DeviceList(List<DeviceBO> deviceBOList);

    @Mapping(source = "number", target = "iotDeviceId")
    @Mapping(source = "position", target = "detailPosition")
    @Mapping(target = "deviceTypeId", constant = "3")
    @Mapping(target = "onlineStatus", expression = "java(com.xhwl.common.enums.device.DeviceOnlineStatusEnum.ONLINE)")
    Device deviceBO2Device(DeviceBO deviceBO);

    default List<DeviceBO> carDeviceJieShunDTOList2DeviceBOList(List<CarDeviceJieShunDTO> carDeviceJieShunDTOList, Integer projectId, Integer productId, Integer categoryId) {
        return carDeviceJieShunDTOList.stream()
                .map(carDeviceJieShunDTO -> carDeviceJieShunDTO2DeviceBO(carDeviceJieShunDTO, projectId, productId, categoryId))
                .collect(Collectors.toList());
    }

    @Mapping(source = "carDeviceJieShunDTO.equipCode", target = "number")
    @Mapping(source = "carDeviceJieShunDTO.equipName", target = "name")
    @Mapping(target = "position", expression = "java(JieShunInputOutputType.toDescription(carDeviceJieShunDTO.getIoType()))")
    DeviceBO carDeviceJieShunDTO2DeviceBO(CarDeviceJieShunDTO carDeviceJieShunDTO, Integer projectId, Integer productId, Integer categoryId);


    //*********Sync KeTop Device*********
    default List<DeviceBO> toDeviceBOListByKeTop(List<ParkingLotDeviceInfoKeTopDTO> parkingLotDeviceInfoKeTopDTOList, Integer projectId, Integer productId, Integer categoryId) {
        return parkingLotDeviceInfoKeTopDTOList.stream()
                .map(parkingLotDeviceInfoKeTopDTO -> toDeviceBOByKeTop(parkingLotDeviceInfoKeTopDTO, projectId, productId, categoryId, null))
                .collect(Collectors.toList());
    }

    @Mapping(target = "number", source = "parkingLotDeviceInfoKeTopDTO.deviceCode")
    @Mapping(target = "name", source = "parkingLotDeviceInfoKeTopDTO.deviceName")
    DeviceBO toDeviceBOByKeTop(ParkingLotDeviceInfoKeTopDTO parkingLotDeviceInfoKeTopDTO, Integer projectId, Integer productId, Integer categoryId, String position);

    @Mapping(target = "number", source = "parkingLotDeviceInfoKeTopDTO.deviceCode")
    @Mapping(target = "name", source = "parkingLotDeviceInfoKeTopDTO.deviceName")
    DeviceBO toDeviceBOByKeTop(Integer id, ParkingLotDeviceInfoKeTopDTO parkingLotDeviceInfoKeTopDTO, Integer projectId, Integer productId, Integer categoryId, String position);

    //*********Sync KeTop Device*********
    //*********Sync ConSon device********

    @Mapping(target = "number", source = "deviceInfoCoSonDTO.vehNumber")
    @Mapping(target = "name", source = "deviceInfoCoSonDTO.sentryboxNo")
    default DeviceBO toDeviceBOByCoSon(DeviceInfoCoSonDTO deviceInfoCoSonDTO, Integer projectId, Integer productId, Integer categoryId) {
        DeviceBO deviceBO = new DeviceBO();

        if (deviceInfoCoSonDTO != null) {
            deviceBO.setNumber(deviceInfoCoSonDTO.getVehNumber());
            deviceBO.setName(deviceInfoCoSonDTO.getSentryboxNo());
            deviceBO.setPosition(deviceInfoCoSonDTO.getVehName());
        }
        if (projectId != null) {
            deviceBO.setProjectId(projectId);
        }
        if (productId != null) {
            deviceBO.setProductId(productId);
        }
        if (categoryId != null) {
            deviceBO.setCategoryId(categoryId);
        }

        return deviceBO;
    }

    @Mapping(target = "number", source = "deviceInfoCoSonDTO.vehNumber")
    @Mapping(target = "name", source = "deviceInfoCoSonDTO.sentryboxNo")
    default DeviceBO toDeviceBOByCoSon(Integer id, DeviceInfoCoSonDTO deviceInfoCoSonDTO, Integer projectId, Integer productId, Integer categoryId) {
        DeviceBO deviceBO = new DeviceBO();

        if (id != null) {
            deviceBO.setId(id);
        }
        if (deviceInfoCoSonDTO != null) {
            deviceBO.setNumber(deviceInfoCoSonDTO.getVehNumber());
            deviceBO.setName(deviceInfoCoSonDTO.getSentryboxNo());
            deviceBO.setPosition(deviceInfoCoSonDTO.getVehName());
        }
        if (projectId != null) {
            deviceBO.setProjectId(projectId);
        }
        if (productId != null) {
            deviceBO.setProductId(productId);
        }
        if (categoryId != null) {
            deviceBO.setCategoryId(categoryId);
        }
        return deviceBO;
    }
    //*************Sync CoSon Device***********
}
